#include "w55mh32.h"
#include <stdint.h>

// 全局变量定义
uint16_t g_pm25_concentration = 0;     // 浓度值
volatile uint8_t g_rx_buffer[4];       // 接收缓冲区
volatile uint8_t g_rx_index = 0;       // 接收索引
volatile uint8_t g_data_ready = 0;     // 数据就绪标志
volatile uint8_t g_checksum_error = 0; // 校验错误标志

// 串口2初始化函数
void pm25_usart2_init(uint32_t baudrate) {
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  // 使能时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

  // 配置TX引脚 (PA0)
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  // 配置RX引脚 (PA3)
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  // 配置串口参数
  USART_InitStructure.USART_BaudRate = baudrate;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl =
      USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  USART_Init(USART2, &USART_InitStructure);

  // 使能接收中断
  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);

  // 配置NVIC
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  // 使能串口
  USART_Cmd(USART2, ENABLE);
}

void usar_t2_irq_handler(void) {

  if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) {
    // 读取接收到的数据
    uint8_t received_byte = USART_ReceiveData(USART2);
    // 帧头检测 (0xA5)
    if (g_rx_index == 0 && received_byte != 0xA5) {
      // 如果不是帧头，重置索引
      g_rx_index = 0;
      return;
    }

    // 存储数据
    g_rx_buffer[g_rx_index] = received_byte;
    g_rx_index++;

    // 检查是否接收到完整帧
    if (g_rx_index >= 4) {
      g_rx_index = 0;   // 重置索引准备接收下一帧
      g_data_ready = 1; // 设置数据就绪标志
    }

    // 清除中断标志
    USART_ClearITPendingBit(USART2, USART_IT_RXNE);
  }
}

void pm25_data_process_usart2(void) {
  // 计算校验和：前三字节的低7位之和
  uint8_t calculated_checksum = (g_rx_buffer[0] & 0x7F) +
                                (g_rx_buffer[1] & 0x7F) +
                                (g_rx_buffer[2] & 0x7F);
  calculated_checksum &= 0x7F; // 保留低7位

  // 获取接收到的校验位（第四字节）
  uint8_t received_checksum = g_rx_buffer[3] & 0x7F;

  // 校验检查
  if (calculated_checksum != received_checksum) {
    g_checksum_error = 1;
    return; // 校验失败，丢弃数据
  }

  g_checksum_error = 0;

  // 计算浓度值
  // 浓度值 = (DATAH[6:0] << 7) | DATAL[6:0]
  g_pm25_concentration =
      ((g_rx_buffer[1] & 0x7F) << 7) | (g_rx_buffer[2] & 0x7F);
}
